//------------------------------------------------------------------
//  POLYEC.h
//------------------------------------------------------------------
/****************************************************************
*                                                               *
*       These are structures used to create elliptic curve      *
*  points and parameters.  "form" is a just a fast way to check *
*  if a2 == 0.                                                  *
*               form            equation                        *
*                                                               *
*                0              y^2 + xy = x^3 + a_6            *
*                1              y^2 + xy = x^3 + a_2*x^2 + a_6  *
*                                                               *
****************************************************************/
typedef struct 
{
        INDEX   form;
        FIELD2N  a2;
        FIELD2N  a6;
} POLY_CURVE;
//------------------------------------------------------------------
//  affine coordinates for a point  
//------------------------------------------------------------------
typedef struct 
{
        FIELD2N  x;
        FIELD2N  y;
} POLY_POINT;
//------------------------------------------------------------------
//  affine coordinates for a point  
//------------------------------------------------------------------
typedef struct 
{
        FIELD2N  X;
        FIELD2N  Z;
} POLY_POINT_LD;
/****************************************************************************
*                                                                           *
*   Implement elliptic curve point addition for polynomial basis form.  	*
*  This follows R. Schroeppel, H. Orman, S. O'Mally, "Fast Key Exchange with*
*  Elliptic Curve Systems", CRYPTO '95, TR-95-03, Univ. of Arizona, Comp.   *
*  Science Dept.                                                            *
****************************************************************************/

void poly_eneg(POLY_POINT* p);

void poly_esum(POLY_POINT* p1, POLY_POINT* p2, POLY_POINT* p3, FIELD2N* irr_poly, POLY_CURVE* curv);
//------------------------------------------------------------------
//  elliptic curve doubling routine for Schroeppel's algorithm over polymomial
//  basis.  Enter with p1, p3 as source and destination as well as curv
//  to operate on.  Returns p3 = 2*p1.
//------------------------------------------------------------------
void poly_edbl(POLY_POINT* p1, POLY_POINT* p3, FIELD2N* irr_poly, POLY_CURVE* curv);
//------------------------------------------------------------------
//  subtract two points on a curve.  just negates p2 and does a sum.
//  Returns p3 = p1 - p2 over curv.
//------------------------------------------------------------------
void poly_esub(POLY_POINT* p1, POLY_POINT* p2, POLY_POINT* p3, FIELD2N* irr_poly, POLY_CURVE* curv);
//------------------------------------------------------------------
//  need to move points around, not just values.  Optimize later.  
//------------------------------------------------------------------
void poly_copy_point(POLY_POINT* p1, POLY_POINT* p2);
//------------------------------------------------------------------
//  Routine to compute kP where k is an integer (base 2, not normal basis)
//	and P is a point on an elliptic curve.  This routine assumes that K
//	is representable in the same bit field as x, y or z values of P.  Since
//	the field size determines the largest possible order, this makes sense.
//  Enter with: integer k, source point P, curve to compute over (curv) 
//  Returns with: result point R.
//
//  Reference: Koblitz, "CM-Curves with good Cryptografic Properties", 
//	Springer-Verlag LNCS #576, p279 (pg 284 really), 1992
//------------------------------------------------------------------
void poly_emul(FIELD2N* k, POLY_POINT* p, POLY_POINT* r, FIELD2N* irr_poly, POLY_CURVE* curv);
//------------------------------------------------------------------
//
//------------------------------------------------------------------
void print_poly_field(char* string, FIELD2N* x);
//------------------------------------------------------------------
//
//------------------------------------------------------------------
void print_poly_point(char* string, POLY_POINT* point);
//------------------------------------------------------------------
//
//------------------------------------------------------------------
void print_poly_curve(char* string, POLY_CURVE* curv);
//------------------------------------------------------------------
// point calculation by Montgomery Ladder with LD algorithm
//------------------------------------------------------------------
void poly_esum_LD(FIELD2N* bpx, POLY_POINT_LD* P1, POLY_POINT_LD* P2, POLY_POINT_LD* P3);
void poly_edlb_LD(POLY_POINT_LD* P1, POLY_POINT_LD* P3, POLY_CURVE* curv);
//void poly_emul_MonLadder_LD();